home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / SML⁄NJ 93+ / Documentation / examples / textbooks / four_lectures / interp5.sml < prev    next >
Encoding:
Text File  |  1995-12-30  |  29.6 KB  |  945 lines  |  [TEXT/R*ch]

  1. (* interp5.sml : the complete type checker and evaluator
  2.                  based on version 2 *)
  3.  
  4. signature INTERPRETER=
  5.    sig
  6.       val interpret: string -> string
  7.       val eval: bool ref
  8.       and tc  : bool ref
  9.    end;
  10.  
  11.                   (* syntax *)
  12.  
  13. signature EXPRESSION =
  14.    sig
  15.       datatype Expression =
  16.          SUMexpr of Expression * Expression   |
  17.          DIFFexpr of Expression * Expression   |
  18.          PRODexpr of Expression * Expression   |
  19.          BOOLexpr of bool   |
  20.          EQexpr of Expression * Expression   |
  21.          CONDexpr of Expression * Expression * Expression   |
  22.          CONSexpr of Expression * Expression   |
  23.          LISTexpr of Expression list   |
  24.          DECLexpr of string * Expression * Expression   |
  25.          RECDECLexpr of string * Expression * Expression   |
  26.          IDENTexpr of string   |
  27.          LAMBDAexpr of string * Expression   |
  28.          APPLexpr of Expression * Expression   |
  29.          NUMBERexpr of int
  30.  
  31.  
  32.       val prExp: int -> Expression -> string
  33.    end;
  34.  
  35.  
  36.               (* parsing *)
  37.  
  38. signature PARSER =
  39.    sig
  40.       structure E: sig type Expression end
  41.  
  42.       exception Lexical of string
  43.       exception Syntax of string
  44.  
  45.       val parse: string -> E.Expression
  46.    end
  47.  
  48.  
  49.                         (* environments *)
  50.  
  51. signature ENVIRONMENT =
  52.    sig
  53.       type 'object Environment
  54.  
  55.       exception Retrieve of string
  56.  
  57.       val emptyEnv: 'object Environment
  58.       val declare: string * 'object * 'object Environment -> 'object Environment
  59.       val retrieve: string * 'object Environment -> 'object
  60.       val fold: (('object * 'result) -> 'result) -> 'result -> 
  61.                    'object Environment -> 'result
  62.       val map: ('object -> 'newobject) -> 'object Environment -> 
  63.                  'newobject Environment
  64.   
  65.       val plus: 'obj Environment * 'obj Environment -> 'obj Environment
  66.  
  67.    end;
  68.  
  69.                         (* evaluation *)
  70. signature VALUE =
  71.    sig
  72.       structure Environment : sig type 'a Environment end
  73.       type Value and Env and Exp
  74.       exception Value
  75.  
  76.       val mkValueNumber: int -> Value
  77.           and unValueNumber: Value -> int
  78.  
  79.       val mkValueBool: bool -> Value
  80.           and unValueBool: Value -> bool
  81.  
  82.       val ValueNil: Value
  83.       val mkValueCons: Value * Value -> Value
  84.           and unValueHead: Value -> Value
  85.           and unValueTail: Value -> Value
  86.  
  87.       val mkValueClos: string * Exp * Env * Env -> Value
  88.           and unValueClos: Value -> string * Exp * Env * Env
  89.  
  90.       val mkEnv: Value Environment.Environment -> Env
  91.           and unEnv: Env -> Value Environment.Environment
  92.  
  93.       val Rec: Env -> Env
  94.  
  95.       exception EqValue
  96.       val eqValue: Value * Value -> bool
  97.       val printValue: Value -> string
  98.    end;
  99.  
  100.  
  101. signature EVALUATOR =
  102.    sig
  103.       structure Exp: sig type Expression end
  104.       structure Val: sig type Exp and Value end
  105.             sharing type Val.Exp = Exp.Expression
  106.       exception Unimplemented
  107.       exception RuntimeError of string
  108.       val evaluate: Exp.Expression -> Val.Value
  109.    end;
  110.  
  111.                   (* type checking *)
  112. signature TYPE =
  113.    sig
  114.       eqtype tyvar
  115.       val freshTyvar: unit -> tyvar
  116.       type Type 
  117.       type TypeScheme
  118.   
  119.       val tyvarsTy: Type -> tyvar list
  120.       and tyvarsTySch: TypeScheme -> tyvar list
  121.  
  122.       val instance: TypeScheme -> Type
  123.  
  124.     (*constructors and decstructors*)
  125.       exception Type
  126.       val mkTypeInt: unit -> Type
  127.           and unTypeInt: Type -> unit
  128.  
  129.       val mkTypeBool: unit -> Type
  130.           and unTypeBool: Type -> unit
  131.  
  132.       val mkTypeList: Type -> Type
  133.           and unTypeList: Type -> Type
  134.  
  135.       val mkTypeArrow:  Type * Type -> Type
  136.           and unTypeArrow: Type -> Type * Type
  137.  
  138.       val mkTypeTyvar: tyvar -> Type
  139.           and unTypeTyvar: Type -> tyvar
  140.  
  141.       val mkTypeScheme: tyvar list * Type -> TypeScheme
  142.           and unTypeScheme: TypeScheme -> tyvar list * Type
  143.  
  144.       type subst
  145.       val Id: subst                     (* the identify substitution;   *)
  146.       val mkSubst: tyvar*Type -> subst     (* make singleton substitution; *)
  147.       val on : subst * Type -> Type     (* application;                 *)
  148.       val onScheme: subst * TypeScheme -> TypeScheme
  149.     
  150.       val oo : subst * subst -> subst   (* composition *)
  151.  
  152.       val prType: Type->string          (* printing *)
  153.    end
  154.  
  155. signature TYPEENV=
  156.  sig
  157.   structure Type : sig type Type and TypeScheme and subst end
  158.   type typeenv
  159.   exception Retrieve of string
  160.   val emptyEnv: typeenv
  161.   val declare: string * Type.TypeScheme * typeenv -> typeenv
  162.   val retrieve: string * typeenv -> Type.TypeScheme
  163.   val close: typeenv * Type.Type -> Type.TypeScheme
  164.   val onTE: Type.subst * typeenv -> typeenv
  165.  end
  166.   
  167.  
  168.  
  169. signature TYPECHECKER =
  170.    sig
  171.       structure Exp: sig type Expression end
  172.       structure Type: sig type Type end
  173.       exception NotImplemented of string
  174.       val typecheck: Exp.Expression -> Type.Type * bool
  175.    end;
  176.  
  177.                   (* the interpreter*)
  178. functor Interpreter
  179.    (structure Ty: TYPE
  180.     structure Value : VALUE
  181.     structure Parser: PARSER
  182.     structure TyCh: TYPECHECKER
  183.     structure Evaluator:EVALUATOR
  184.       sharing Parser.E = TyCh.Exp = Evaluator.Exp 
  185.           and type Value.Exp = Parser.E.Expression
  186.           and TyCh.Type = Ty
  187.           and Evaluator.Val = Value
  188.    ): INTERPRETER=
  189.  
  190. struct
  191.   val eval= ref true    (* toggle for evaluation *)
  192.   and tc  = ref true    (* toggle for type checking *)
  193.   fun interpret'(str)=
  194.     let val abstsyn= Parser.parse str
  195.         val (typestr,ok)= 
  196.                      if !tc then 
  197.                        let val (ty, ok) = TyCh.typecheck abstsyn
  198.                         in (Ty.prType(ty),ok)
  199.                        end
  200.                      else ("(disabled)",false)
  201.         val valuestr= if !eval andalso ok then 
  202.                          Value.printValue(Evaluator.evaluate abstsyn)
  203.                       else "(disabled)"
  204.              
  205.     in  valuestr ^ " : " ^ typestr 
  206.     end
  207.     handle Evaluator.Unimplemented => "Evaluator not fully implemented"
  208.          | TyCh.NotImplemented msg => "Type Checker not fully implemented " ^ msg
  209.          | Value.Value   => "Run-time error"
  210.          | Evaluator.RuntimeError msg => "Run-time error: " ^ msg
  211.          | Parser.Syntax msg => "Syntax Error: " ^ msg
  212.          | Parser.Lexical msg=> "Lexical Error: " ^ msg
  213.  
  214.   fun interpret(str) = 
  215.      let val separator = "\n--------------------------------\n"
  216.          val result = interpret' str
  217.       in output(std_out, separator);
  218.          output(std_out, result);
  219.          output(std_out, separator ^ "\n");
  220.          ""
  221.      end
  222. end;
  223.  
  224.                     (* the evaluator *)
  225. functor Evaluator
  226.   (structure Expression: EXPRESSION
  227.    structure Env: ENVIRONMENT
  228.    structure Value: VALUE
  229.              sharing type Value.Exp = Expression.Expression
  230.              sharing Value.Environment = Env
  231.   ):EVALUATOR=
  232.  
  233.    struct
  234.       structure Exp= Expression
  235.       structure Val= Value
  236.       type Env = Val.Value Env.Environment
  237.  
  238.       exception Unimplemented
  239.       exception RuntimeError of string
  240.       local
  241.          open Expression Value
  242.          fun evaluate(E, exp) =
  243.             case exp
  244.               of BOOLexpr b => mkValueBool b
  245.                | NUMBERexpr i => mkValueNumber i
  246.                | SUMexpr(e1, e2) =>
  247.                     let val e1' = evaluate(E, e1)
  248.                         val e2' = evaluate(E, e2)
  249.                     in
  250.                        mkValueNumber(unValueNumber e1' + unValueNumber e2')
  251.                     end
  252.  
  253.                | DIFFexpr(e1, e2) =>
  254.                     let val e1' = evaluate(E, e1)
  255.                         val e2' = evaluate(E, e2)
  256.                     in
  257.                        mkValueNumber(unValueNumber e1' - unValueNumber e2')
  258.                     end
  259.  
  260.                | PRODexpr(e1, e2) =>
  261.                     let val e1' = evaluate(E, e1)
  262.                         val e2' = evaluate(E, e2)
  263.                     in
  264.                        mkValueNumber(unValueNumber e1' * unValueNumber e2')
  265.                     end
  266.  
  267.                | EQexpr(e1,e2)=> 
  268.                     let val v1 = evaluate(E,e1)
  269.                         val v2 = evaluate(E,e2)
  270.                      in mkValueBool(eqValue(v1,v2))
  271.                     end
  272.                | CONDexpr(e1,e2,e3)=> 
  273.                     let val v1 = evaluate(E, e1)
  274.                      in if eqValue(v1,mkValueBool true) then evaluate(E,e2)
  275.                         else evaluate(E, e3)
  276.                     end
  277.                | CONSexpr(e1, e2) =>
  278.                     let val v1 = evaluate(E, e1)
  279.                         val v2 = evaluate(E, e2)
  280.                      in mkValueCons(v1,v2)
  281.                     end
  282.                | LISTexpr [] => ValueNil
  283.                | LISTexpr (hd::tl)=> 
  284.                     evaluate(E, CONSexpr(hd, LISTexpr tl))
  285.                | DECLexpr(id,e1,e2) => 
  286.                     let val v1 = evaluate(E,e1)
  287.                         val E' = Env.declare(id,v1,E)
  288.                      in evaluate(E', e2)
  289.                     end
  290.                | RECDECLexpr(f,e1,e2) => 
  291.                     let val v1 = evaluate(E, e1)
  292.                         val ? = unValueClos v1
  293.                                 handle Value=> raise RuntimeError(
  294.                            "recursively  defined value is not a function")
  295.                         val Env0 = mkEnv(Env.declare(f,v1,Env.emptyEnv))
  296.                         val recE0 = Rec Env0
  297.                         val newE = Env.plus(E, unEnv recE0)
  298.                      in evaluate(newE,e2)
  299.                     end
  300.  
  301.                | IDENTexpr id=> 
  302.                     Env.retrieve(id,E)
  303.                | APPLexpr(e1,e2)=> 
  304.                    let val v1 = evaluate(E,e1)
  305.                        val v2 = evaluate(E,e2)
  306.                        val (id',exp',Env',Env'')= unValueClos v1
  307.                        val recE'= Env.plus(unEnv Env', unEnv(Rec Env''))
  308.                     in evaluate(Env.declare(id',v2,recE'), exp')
  309.                    end
  310.                | LAMBDAexpr(x,e) => 
  311.                    mkValueClos(x,e,mkEnv E, mkEnv Env.emptyEnv)
  312.                    
  313.  
  314.  
  315.       in
  316.          val evaluate = fn(e) => evaluate(Env.emptyEnv,e)
  317.       end
  318.    end;
  319.  
  320.                         (* the type checker *)   
  321. signature UNIFY=
  322.    sig
  323.       structure Type: sig type Type and subst end
  324.       exception NotImplemented of string
  325.       exception Unify
  326.       val unify: Type.Type * Type.Type -> Type.subst
  327.    end;
  328.  
  329. functor TypeCheckerRecovery(structure Ex: EXPRESSION
  330.                             structure Ty: TYPE
  331.                             structure List: LISTUTIL): 
  332.   sig 
  333.    val report: Ex.Expression * int * Ty.subst * string list ->
  334.                Ty.subst * Ty.Type * bool
  335.   end=
  336.  
  337. struct
  338.   exception Recovery of int
  339.   val messages= [
  340. (1, fn[t2]=> 
  341. "expected the second operand to cons to be of list type" ^
  342. "\n   found :   " ^  t2
  343. |        _ => raise Recovery 1),
  344.  
  345. (2, fn[t1,t2]=>
  346. "the type of the first list element differs from the type of the others " ^
  347. "\n   first element  :   " ^  t1 ^
  348. "\n   other elements :   " ^  t2
  349. |        _ => raise Recovery 2),
  350.  
  351. (3, fn[t1,t2]=>
  352. "left and right hand sides of = have different types" ^
  353. "\n  left-hand side  :  " ^  t1 ^
  354. "\n  right-hand side :  " ^  t2
  355. |        _ => raise Recovery 3),
  356.  
  357. (4, fn[t1]=>
  358. "expected boolean expression between `if' and `then';" ^
  359. "\n  found:  " ^  t1
  360. |        _ => raise Recovery 4),
  361.  
  362. (5, fn[t2,t3]=>
  363. "`then' and `else' branches have different types" ^
  364. "\n  `then' branch :  " ^  t2 ^
  365. "\n  `else' branch :  " ^  t3
  366. |        _ => raise Recovery 5),
  367.  
  368. (6, fn[t1,t2]=>
  369. "the domain type of the function differs from the type of the argument " ^
  370. "\nto which it is applied" ^
  371. "\n  function domain type : " ^  t1 ^
  372. "\n  argument        type : " ^  t2
  373. |        _ => raise Recovery 6),
  374.  
  375. (7, fn[t1]=>
  376. "I expected this expression, which is an argument " ^
  377. "\nto a numeric operator, to have type int; but I " ^
  378. "\nfound : " ^  t1
  379. |        _ => raise Recovery 7),
  380.  
  381. (8, fn [x] =>
  382. "the identifier " ^ x ^ " has not been declared"
  383. |        _ => raise Recovery 8),
  384.  
  385. (9, fn [t] =>
  386. "although the above expression occurs in " ^
  387. "\napplication position, I have found it to " ^
  388. "\nhave type :  " ^ t
  389. |        _ => raise Recovery 9)
  390.  
  391.  
  392.  
  393. ]
  394.  
  395.   fun report(exp, i, S, stringlist) =
  396.       let val msgf = List.lookup messages i
  397.                     handle List.Lookup => raise Recovery(i)
  398.           val sep = "\n----------------\n"
  399.           val freshty = Ty.mkTypeTyvar (Ty.freshTyvar())
  400.           val msg   = "Type Error in expression:\n   " ^ Ex.prExp 60 exp ^
  401.                       "\nClue: " ^  msgf stringlist ^ "\n"
  402.  
  403.        in 
  404.           output(std_out, sep);
  405.           output(std_out, msg);
  406.           (S,freshty,false)
  407.       end
  408. end;
  409.  
  410.  
  411.  
  412. functor TypeChecker
  413.   (structure Ex: EXPRESSION
  414.    structure Ty: TYPE
  415.    structure TyEnv: TYPEENV
  416.    structure Unify: UNIFY 
  417.       sharing Unify.Type = Ty = TyEnv.Type
  418.    structure List: LISTUTIL
  419.   ): TYPECHECKER=
  420. struct
  421.   infixr on         val (op on) = Ty.on
  422.   infixr onscheme   val op onscheme = Ty.onScheme
  423.   infixr onTE       val op onTE = TyEnv.onTE
  424.   infixr oo         val op oo = Ty.oo
  425.  
  426.   structure Exp = Ex
  427.   structure Type = Ty
  428.   structure Recovery= TypeCheckerRecovery(
  429.     structure Ex = Ex
  430.     structure Ty = Ty
  431.     structure List = List)
  432.  
  433.   exception NotImplemented of string
  434.   exception Recover of Ex.Expression * int * Ty.subst * string list ;
  435.  
  436.   fun tc (TE: TyEnv.typeenv, exp: Ex.Expression): 
  437.         Ty.subst *Ty.Type * bool =
  438.    (case exp of
  439.       Ex.BOOLexpr b => (Ty.Id,Ty.mkTypeBool(),true)
  440.     | Ex.NUMBERexpr _ => (Ty.Id,Ty.mkTypeInt(),true)
  441.     | Ex.SUMexpr(e1,e2)  => checkIntBin(TE,e1,e2)
  442.     | Ex.DIFFexpr(e1,e2) => checkIntBin(TE,e1,e2)
  443.     | Ex.PRODexpr(e1,e2) => checkIntBin(TE,e1,e2)
  444.     | Ex.LISTexpr [] =>
  445.          let val new = Ty.freshTyvar ()
  446.           in (Ty.Id,Ty.mkTypeList(Ty.mkTypeTyvar  new),true)
  447.          end
  448.     | Ex.LISTexpr(e::es) => tc (TE, Ex.CONSexpr(e,Ex.LISTexpr es))
  449.     | Ex.CONSexpr(e1,e2) =>
  450.        (let val (S1,t1,ok1) = tc(TE, e1)
  451.             val (S2,t2,ok2) = tc(S1 onTE TE, e2)
  452.             val new = Ty.freshTyvar ()
  453.             val newt= Ty.mkTypeTyvar new
  454.             val t2' = Ty.mkTypeList newt
  455.             val S3 = Unify.unify(t2, t2')
  456.                      handle Unify.Unify=> 
  457.                      raise Recover(e2, 1, (S2 oo S1), [Ty.prType t2])
  458.             val S4 = Unify.unify(S3 on newt,S3 oo S2 on t1)
  459.                      handle Unify.Unify=>
  460.                      raise Recover(exp, 2, (S3 oo S2 oo S1), 
  461.                        [Ty.prType (S3 oo S2 on t1), Ty.prType (S3 on newt)])
  462.          in (S4 oo S3 oo S2 oo S1, S4 oo S3 on t2, ok1 andalso ok2)
  463.         end handle Recover q => Recovery.report q)
  464.     | Ex.EQexpr(e1,e2)=> 
  465.        (let val (S1,t1,ok1) = tc(TE,e1)
  466.             val (S2,t2,ok2) = tc(S1 onTE TE, e2)
  467.             val S3 = Unify.unify(S2 on t1, t2)
  468.                      handle Unify.Unify=>
  469.                      raise Recover(exp, 3, (S2 oo S1), [Ty.prType (S2 on t1), 
  470.                           Ty.prType t2])
  471.          in (S3 oo S2 oo S1, Ty.mkTypeBool(), ok1 andalso ok2)
  472.         end  handle Recover q=> Recovery.report q)
  473.     | Ex.CONDexpr(b,e1,e2)=> 
  474.         (let val (S1,t1,ok1) = tc(TE,b)
  475.              val S1' = Unify.unify(t1,Ty.mkTypeBool())
  476.                        handle Unify.Unify=>
  477.                        raise Recover(exp, 4, S1, [Ty.prType t1])
  478.              val (S2,t2,ok2) = tc(S1 onTE TE, e1)
  479.              val (S3,t3,ok3) = tc(S2 oo S1 onTE TE, e2)
  480.              val S3' = Unify.unify(S3 on t2,t3)
  481.                        handle Unify.Unify=>
  482.                        raise Recover(exp, 5, (S3 oo S2 oo S1' oo S1), 
  483.                        [Ty.prType (S3 on t2), Ty.prType t3])
  484.           in (S3' oo S3 oo S2 oo S1' oo S1, 
  485.               S3' oo S3 on t2,
  486.               ok1 andalso ok2 andalso ok3)
  487.          end handle Recover q=> Recovery.report q)
  488.     | Ex.DECLexpr(x,e1,e2) => 
  489.          let val (S1,t1,ok1) = tc(TE,e1);
  490.              val typeScheme = TyEnv.close(S1 onTE TE,t1)
  491.              val (S2,t2,ok2) = tc(TyEnv.declare(x,typeScheme,TE), e2)
  492.           in (S2 oo S1, t2, ok1 andalso ok2)
  493.          end
  494.     | Ex.RECDECLexpr(fid,e1,e2)=>
  495.          let val new = Ty.mkTypeScheme([],
  496.                          Ty.mkTypeTyvar(Ty.freshTyvar()))
  497.              val TE' = TyEnv.declare(fid,new,TE)
  498.              val (S1,t1, ok1) = tc(TE',e1)
  499.              val (S2,t2, ok2) = tc(S1 onTE TE', e2)
  500.           in
  501.              (S2 oo S1, t2, ok1 andalso ok2)
  502.          end
  503.     | Ex.IDENTexpr x   => 
  504.          ((Ty.Id, Ty.instance(TyEnv.retrieve(x,TE)), true)
  505.          handle TyEnv.Retrieve _=> 
  506.           Recovery.report(exp,8,Ty.Id,[x]))
  507.     | Ex.LAMBDAexpr(x,e)=>
  508.          let val newty = Ty.mkTypeTyvar(Ty.freshTyvar())
  509.              val new_scheme = Ty.mkTypeScheme([], newty)
  510.              val TE' = TyEnv.declare(x,new_scheme,TE)
  511.              val (S1,t1,ok1) = tc(TE', e)
  512.           in (S1, Ty.mkTypeArrow(S1 on newty,t1), ok1)
  513.          end
  514.  
  515.     | Ex.APPLexpr(e1,e2)=>
  516.         (let val (S1,t1,ok1) = tc(TE, e1)
  517.              val new =  Ty.mkTypeTyvar(Ty.freshTyvar())
  518.              val new' = Ty.mkTypeTyvar(Ty.freshTyvar())
  519.              val arrow1=Ty.mkTypeArrow(new,new')
  520.              val S1' = Unify.unify(arrow1,t1)
  521.                  handle Unify.Unify=>
  522.                  raise Recover(e1,9,S1,[Ty.prType t1])
  523.              val (S2,t2,ok2) = tc((S1' oo S1) onTE TE, e2)
  524.              val new2 = Ty.mkTypeTyvar(Ty.freshTyvar())
  525.              val arrow2 = Ty.mkTypeArrow(t2,new2) 
  526.              val S3 = Unify.unify(arrow2, (S2 oo S1') on t1)
  527.                  handle Unify.Unify=> 
  528.                  raise Recover(exp, 6, (S2 oo S1' oo S1 ), 
  529.                     [Ty.prType ((S2 oo S1') on new),Ty.prType  t2])
  530.           in (S3 oo S2 oo S1' oo S1,
  531.               S3 on new2, ok1 andalso ok2)
  532.          end  handle Recover q=> Recovery.report q)
  533.  
  534.    )handle Unify.NotImplemented msg => raise NotImplemented msg
  535.        
  536.   and checkIntBin(TE,e1,e2) =
  537.    (let val (S1,t1,ok1) = tc(TE,e1)
  538.         val S1'  = Unify.unify(t1, Ty.mkTypeInt())
  539.                  handle Unify.Unify=> 
  540.                  raise Recover(e1, 7, S1, [Ty.prType t1])
  541.         val (S2,t2,ok2) = tc((S1' oo S1) onTE TE,e2)
  542.         val S2' =  Unify.unify(t2, Ty.mkTypeInt())
  543.                    handle Unify.Unify=> 
  544.                    raise Recover(e2, 7, (S2 oo S1' oo S1), [Ty.prType t2])
  545.      in (S2' oo S2 oo S1' oo S1, Ty.mkTypeInt(), ok1 andalso ok2)
  546.     end handle Recover q=> Recovery.report q);
  547.  
  548.   fun typecheck(e) = let val (_,ty,ok) =
  549.                           tc(TyEnv.emptyEnv,e)
  550.                       in (ty,ok)
  551.                      end
  552.  
  553. end; (*TypeChecker*)
  554.  
  555.  
  556. functor Unify(Ty:TYPE):UNIFY=
  557. struct
  558.    structure Type = Ty
  559.    exception NotImplemented of string
  560.    exception Unify
  561.  
  562.    infix on 
  563.    val op on = Ty.on
  564.    infix oo
  565.    val op oo = Ty.oo
  566.    fun occurs(tv:Ty.tyvar,t:Ty.Type):bool=
  567.      (Ty.unTypeInt t; false)              handle Ty.Type=>
  568.      (Ty.unTypeBool t; false)             handle Ty.Type=>
  569.      let val tv' = Ty.unTypeTyvar t
  570.      in  tv=tv'
  571.      end                                  handle Ty.Type=>
  572.      let val t'  = Ty.unTypeList t
  573.      in  occurs(tv,t')
  574.      end                                  handle Ty.Type=>
  575.      let val (t1,t2)= Ty.unTypeArrow t
  576.      in occurs(tv, t1) orelse occurs(tv, t2)
  577.      end                                  handle Ty.Type=>
  578.    raise NotImplemented "(the occur check)"
  579.  
  580.  
  581.    fun unify(t,t')=
  582.    let val tv = Ty.unTypeTyvar t
  583.     in let val tv' = Ty.unTypeTyvar t'
  584.         in Ty.mkSubst(tv,t')
  585.        end                                handle Ty.Type=>
  586.        if occurs(tv,t') then raise Unify
  587.        else Ty.mkSubst(tv,t')
  588.    end                                  handle Ty.Type=>
  589.    let val tv' = Ty.unTypeTyvar t'
  590.     in if occurs(tv',t) then raise Unify
  591.        else Ty.mkSubst(tv',t)
  592.    end                           handle Ty.Type=>
  593.    let val ? = Ty.unTypeInt t
  594.     in let val ? = Ty.unTypeInt t'
  595.         in Ty.Id
  596.        end handle Ty.Type=> raise Unify
  597.    end                    handle Ty.Type =>
  598.    let val ? = Ty.unTypeBool t
  599.     in let val ? = Ty.unTypeBool t'
  600.         in Ty.Id
  601.        end handle Ty.Type=> raise Unify
  602.    end                    handle Ty.Type=>
  603.    let val t = Ty.unTypeList t
  604.     in let val t' = Ty.unTypeList t'
  605.         in unify(t,t')
  606.        end handle Ty.Type => raise Unify
  607.    end                     handle Ty.Type=>
  608.    let val (t1,t2)= Ty.unTypeArrow(t)
  609.     in let val (t1',t2') = Ty.unTypeArrow(t')
  610.         in let val S1 = unify(t1,t1')
  611.                val S2 = unify(S1 on t2, S1 on t2')
  612.             in S2 oo S1
  613.            end
  614.        end handle Ty.Type => raise Unify
  615.    end                     handle Ty.Type=>
  616.    raise NotImplemented "(unify)"     
  617.  
  618. end; (*Unify*)
  619.   
  620.                      (* the basics -- nullary functors *)
  621.  
  622.  
  623. functor Type(structure List:LISTUTIL
  624.              structure Print: PRINTUTIL) :TYPE =
  625. struct
  626.   type tyvar = int
  627.   val freshTyvar =
  628.       let val r= ref 0 in fn()=>(r:= !r +1; !r) end
  629.   datatype Type = INT
  630.                 | BOOL
  631.                 | LIST of Type
  632.                 | ARROW of Type * Type 
  633.                 | TYVAR of tyvar  
  634.  
  635.   datatype TypeScheme = FORALL of tyvar list * Type
  636.  
  637.   fun tyvarsTy INT = []
  638.     | tyvarsTy BOOL = []
  639.     | tyvarsTy (LIST ty) = tyvarsTy ty
  640.     | tyvarsTy (ARROW(ty,ty')) = List.union(tyvarsTy ty, tyvarsTy ty')
  641.     | tyvarsTy (TYVAR tyvar) = [tyvar];
  642.  
  643.   fun tyvarsTySch(FORALL(tyvarlist, ty))= List.minus(tyvarsTy ty, tyvarlist)
  644.  
  645.  
  646.   fun instance(FORALL(tyvars,ty))=
  647.   let val old_to_new_tyvars = map (fn tv=>(tv,freshTyvar())) tyvars
  648.       exception Find;
  649.       fun find(tv,[]:(tyvar*tyvar)list)= raise Find
  650.       |   find(tv,(tv',new_tv)::rest)=
  651.           if tv=tv' then new_tv else find(tv,rest)
  652.       fun ty_instance INT = INT
  653.       |   ty_instance BOOL = BOOL
  654.       |   ty_instance (LIST t) = LIST(ty_instance t)
  655.       |   ty_instance (ARROW(t,t'))= ARROW(ty_instance t, ty_instance t')
  656.       |   ty_instance (TYVAR tv) = 
  657.              TYVAR(find(tv,old_to_new_tyvars)
  658.                    handle Find=> tv)
  659.  
  660.   in 
  661.      ty_instance ty
  662.   end
  663.              
  664.  
  665.   exception Type
  666.  
  667.   fun mkTypeInt() = INT
  668.   and unTypeInt(INT)=()
  669.     | unTypeInt(_)= raise Type
  670.  
  671.   fun mkTypeBool() = BOOL
  672.   and unTypeBool(BOOL)=()
  673.     | unTypeBool(_)= raise Type
  674.  
  675.   fun mkTypeList(t)=LIST t
  676.   and unTypeList(LIST t)= t
  677.     | unTypeList(_)= raise Type
  678.  
  679.   fun mkTypeArrow(t,t')= ARROW(t,t')
  680.   and unTypeArrow(ARROW(t,t'))= (t,t')
  681.     | unTypeArrow(_) = raise Type
  682.  
  683.   fun mkTypeTyvar tv = TYVAR tv
  684.   and unTypeTyvar(TYVAR tv) = tv
  685.     | unTypeTyvar _ = raise Type
  686.   
  687.   fun mkTypeScheme(l,ty)= FORALL(l,ty)
  688.   and unTypeScheme(FORALL(l,ty))= (l,ty)
  689.  
  690.   type subst = Type -> Type
  691.  
  692.   fun Id x = x
  693.   fun mkSubst(tv,ty)=
  694.      let fun su(TYVAR tv')= if tv=tv' then ty else TYVAR tv'
  695.          |   su(INT) = INT
  696.          |   su(BOOL)= BOOL
  697.          |   su(LIST ty') = LIST (su ty')
  698.          |   su(ARROW (ty,ty'))= ARROW(su ty, su ty')
  699.       in su
  700.      end
  701.  
  702.  
  703.   fun on(S,t)= S(t)
  704.   infixr on
  705.   fun onScheme(S,FORALL(bounds,ty)) = 
  706.       let val fv = tyvarsTy ty
  707.           val fvrange= 
  708.            List.fold(fn (tv,res)=>
  709.                       List.union(tyvarsTy(S(TYVAR tv)),res))
  710.                     []
  711.                     fv
  712.           val criticals= List.intersect(bounds, fvrange)
  713.           val criticals'= map (freshTyvar o (fn _=>())) 
  714.                           criticals
  715.           val renlist = List.zip(criticals,criticals')
  716.           fun renaming(TYVAR tv) =TYVAR(List.lookup renlist tv
  717.                                         handle List.Lookup=>tv)
  718.             | renaming(INT)=INT
  719.             | renaming(BOOL)=BOOL
  720.             | renaming(LIST ty)= (LIST (renaming ty))
  721.             | renaming(ARROW(ty,ty'))= ARROW(renaming ty, renaming ty')
  722.  
  723.           val bounds'= List.map (fn tv=> List.lookup renlist tv
  724.                                          handle List.Lookup => tv)
  725.                                 bounds
  726.                             
  727.           val ty'= S on renaming on ty
  728.        in FORALL(bounds',ty')
  729.       end
  730.  
  731.   val oo = op o; (* composition of substitutions is just
  732.                     function composision *)
  733.  
  734.  
  735.  
  736.   fun prType INT = "int"
  737.   |   prType BOOL= "bool"
  738.   |   prType (LIST ty) = "(" ^ prType ty ^ ")list"
  739.   |   prType (ARROW(ty,ty'))= "(" ^ prType ty ^ "->" ^ prType ty' ^ ")"
  740.   |   prType (TYVAR tv) = "a" ^ Print.intToString tv
  741. end;
  742.  
  743. functor Environment():ENVIRONMENT =
  744. struct
  745.    type 'a Environment = (string *  'a )list
  746.  
  747.    exception Retrieve of string;
  748.    
  749.    val emptyEnv = [];
  750.  
  751.    fun declare(s:string,obj:'a,e:'a Environment)=
  752.        (s,obj)::e
  753.  
  754.    fun retrieve(s,[])= raise Retrieve(s)
  755.    |   retrieve(s,(s',obj)::rest) =
  756.            if s=s' then obj else retrieve(s,rest)
  757.  
  758.    fun map f [] = []
  759.      | map f ((hd as (key,obj))::tl)= (key, f(obj)) :: map f tl
  760.  
  761.    fun fold f r [] = r
  762.      | fold f r ((hd as (key,obj))::tl)= f(obj,fold f r tl)
  763.  
  764.    fun plus(E1,E2) = E2 @ E1
  765.  
  766.  
  767. end;
  768.  
  769.  
  770. functor TypeEnv(structure Type: TYPE 
  771.                 structure E: ENVIRONMENT 
  772.                 structure List: LISTUTIL): TYPEENV=
  773. struct
  774.   structure Type = Type
  775.   structure E = Environment()
  776.   open E
  777.   type typeenv = Type.TypeScheme Environment
  778.   
  779.   fun close(TE, ty)= 
  780.       let fun f(tyscheme, tyvars)= List.union(Type.tyvarsTySch tyscheme,
  781.                                               tyvars)
  782.           val tyvarsTE = E.fold f [] TE
  783.           val bound = List.minus(Type.tyvarsTy ty, tyvarsTE)
  784.        in Type.mkTypeScheme(bound,ty)
  785.       end;
  786.  
  787.   fun onTE(S,TE)=
  788.       E.map(fn(scheme)=> Type.onScheme(S,scheme)) TE
  789. end;
  790.  
  791. functor Expression(structure List: LISTUTIL
  792.                    structure Print: PRINTUTIL): EXPRESSION =
  793.    struct
  794.       type 'a pair = 'a * 'a
  795.  
  796.       datatype Expression =
  797.          SUMexpr of Expression pair   |
  798.          DIFFexpr of Expression pair   |
  799.          PRODexpr of Expression pair   |
  800.          BOOLexpr of bool   |
  801.          EQexpr of Expression pair   |
  802.          CONDexpr of Expression * Expression * Expression   |
  803.          CONSexpr of Expression pair   |
  804.          LISTexpr of Expression list   |
  805.          DECLexpr of string * Expression * Expression   |
  806.          RECDECLexpr of string * Expression * Expression   |
  807.          IDENTexpr of string   |
  808.          LAMBDAexpr of string * Expression   |
  809.          APPLexpr of Expression * Expression   |
  810.          NUMBERexpr of int
  811.  
  812.       fun pr(SUMexpr p) = printPair "+" p
  813.         | pr(DIFFexpr p) = printPair "-" p
  814.         | pr(PRODexpr p) = printPair "*" p
  815.         | pr(BOOLexpr true) = " true"
  816.         | pr(BOOLexpr false) = " false"
  817.         | pr(EQexpr p) = printPair "=" p
  818.         | pr(CONDexpr(e1,e2,e3))=
  819.            " if" ^ pr(e1) ^ " then" ^ pr(e2) ^
  820.            " else" ^ pr(e3)
  821.         | pr(CONSexpr p) = printPair "::" p
  822.         | pr(LISTexpr l) = prList l
  823.         | pr(DECLexpr(f,e1,e2))=
  824.            " let " ^ f ^ "=" ^ pr(e1) ^
  825.            " in" ^ pr e2 ^ " end"
  826.         | pr(RECDECLexpr(f,e1,e2))=
  827.            " let rec " ^ f ^ "=" ^ pr(e1) ^
  828.            " in" ^ pr e2 ^ " end"
  829.         | pr(IDENTexpr f)= " " ^ f
  830.         | pr(LAMBDAexpr(x,e))= " fn " ^ x ^ "=>" ^ pr(e)
  831.         | pr(APPLexpr(e1,e2))= pr e1 ^ pr e2
  832.         | pr(NUMBERexpr i)= " " ^ Print.intToString i
  833.       and printPair operator (e1,e2) = pr e1 ^ " " ^ operator ^
  834.             pr e2
  835.       and prList l = "[" ^ prList' l ^ "]"
  836.       and prList' [] = ""
  837.         | prList' [e] = pr e
  838.         | prList'(hd::tl)= pr hd ^ "," ^ prList' tl
  839.  
  840.  
  841.       fun prExp n e =
  842.           let val s = pr e
  843.               val Size = size s
  844.            in if Size <= n then s
  845.               else
  846.                  let val slist = explode s
  847.                      val half = (n-3)div 2
  848.                      val initial = List.prefix(slist,half)
  849.                      val final = rev(List.prefix(rev slist,half))
  850.                   in implode(initial @ (explode "...") @ final)
  851.                  end
  852.           end
  853.    end;
  854.  
  855.  
  856. functor Value(structure Env: ENVIRONMENT
  857.               structure Exp : EXPRESSION
  858.               structure Print: PRINTUTIL): VALUE =
  859.    struct
  860.       type 'a pair = 'a * 'a
  861.  
  862.       type Exp = Exp.Expression
  863.       structure Environment= Env
  864.  
  865.       datatype Value = NUMBERvalue of int   |
  866.                        BOOLvalue of bool   |
  867.                        NILvalue   |
  868.                        CONSvalue of Value pair |
  869.                CLOS of string
  870.                             *  Exp
  871.                             *  Env * Env
  872.            and Env   = ENV of Value Env.Environment
  873.  
  874.       exception Value
  875.  
  876.       val mkValueNumber = NUMBERvalue
  877.       val mkValueBool = BOOLvalue
  878.  
  879.       val ValueNil = NILvalue
  880.       val mkValueCons = CONSvalue
  881.  
  882.       val mkValueClos = CLOS
  883.       val mkEnv       = ENV
  884.  
  885.  
  886.       fun unValueNumber(NUMBERvalue(i)) = i   |
  887.           unValueNumber(_) = raise Value
  888.  
  889.       fun unValueBool(BOOLvalue(b)) = b   |
  890.           unValueBool(_) = raise Value
  891.  
  892.       fun unValueHead(CONSvalue(c, _)) = c   |
  893.           unValueHead(_) = raise Value
  894.  
  895.       fun unValueTail(CONSvalue(_, c)) = c   |
  896.           unValueTail(_) = raise Value
  897.  
  898.       fun unValueClos(CLOS q) = q |
  899.           unValueClos(_) = raise Value
  900.  
  901.       fun unEnv(ENV e) = e
  902.         
  903.      
  904.       exception EqValue
  905.  
  906.       fun eqValue(NUMBERvalue v,NUMBERvalue v') = v=v' |
  907.           eqValue(BOOLvalue v, BOOLvalue v') = v=v' |
  908.           eqValue(NILvalue,NILvalue) = true |
  909.           eqValue(CONSvalue(v1,v2),CONSvalue(v1',v2'))= 
  910.              eqValue(v1,v1') andalso eqValue(v2,v2') |
  911.           eqValue(CLOS _, _) = raise EqValue |
  912.           eqValue(_, CLOS _) = raise EqValue |
  913.           eqValue (_,_) = false
  914.           
  915.  
  916.           
  917.                  
  918.  
  919.       (* unfolding of environments for recursion*)
  920.  
  921.       fun Rec(E as (ENV env))=
  922.           let fun unfold(CLOS(id',exp',E',E'')) = CLOS(id',exp',E',E)
  923.                 | unfold (v) = v
  924.            in ENV(Env.map unfold env)
  925.           end
  926.           
  927.  
  928.  
  929.                 (* Pretty-printing *)
  930.       fun printValue(NUMBERvalue(i)) = " " ^ Print.intToString(i)   |
  931.           printValue(BOOLvalue(true)) = " true"   |
  932.           printValue(BOOLvalue(false)) = " false"   |
  933.           printValue(NILvalue) = "[]"   |
  934.           printValue(CONSvalue(cons)) = "[" ^ printValueList(cons) ^ "]" |
  935.           printValue(CLOS(id,_,_,_)) = "<" ^ id ^ ",_,_,_>"
  936.           
  937.           and printValueList(hd, NILvalue) = printValue(hd)   |
  938.               printValueList(hd, CONSvalue(tl)) =
  939.                  printValue(hd) ^ ", " ^ printValueList(tl)   |
  940.               printValueList(_) = raise Value
  941.           
  942.    end;
  943.  
  944.  
  945.